using System;
using FireStarterModeller.BO;
using FireStarterModeller.Test.BO;
using FireStarterModeller.UI;
using Habanero.Base;
using Habanero.Faces.Base;
using Habanero.Faces.Win;
using Habanero.Util;
using NUnit.Framework;
using DockStyle=Habanero.Faces.Base.DockStyle;

namespace FireStarterModeller.Test.UI
{
    [TestFixture]
    public class TestDMSolutionControl
    {
        [TestFixtureSetUp]
        public void SetupFixture()
        {
            UITestUtils.SetupFixture();
        }


        [SetUp]
        public virtual void SetupTest()
        {
            UITestUtils.SetupTest();

        }

        [Test]
        public void Test_Construction()
        {
            //--------------- Set up test pack ------------------
            //--------------- Test Preconditions ----------------
            //--------------- Execute Test ----------------------
            DMSolutionControl solutionControl = new DMSolutionControl(new ControlFactoryWin());
            //--------------- Test Result -----------------------
            Assert.AreEqual(1, solutionControl.Controls.Count);
            Assert.IsInstanceOf(typeof(IPanel), solutionControl.Controls[0]);
            Assert.IsTrue(solutionControl.DMClassGridSelectorControl.Visible);
            //Assert.IsTrue(solutionControl.TreeViewSelectorControl.Visible);
        }

        [Test]
        public void Test_SelectorPanel()
        {
            //--------------- Set up test pack ------------------
            //--------------- Test Preconditions ----------------
            //--------------- Execute Test ----------------------
            DMSolutionControl solutionControl = new DMSolutionControl(new ControlFactoryWin());
            //--------------- Test Result -----------------------
            IPanel selectorPanel = (IPanel) solutionControl.Controls[0];
            Assert.AreEqual(2, selectorPanel.Controls.Count);
            //Assert.AreEqual(4, selectorPanel.Controls.Count);
            //Assert.IsInstanceOf(typeof(DMClassTreeViewSelectorControl), selectorPanel.Controls[0]);
            Assert.IsInstanceOf(typeof(DMClassGridSelectorControl), selectorPanel.Controls[0]);
            //Assert.IsInstanceOf(typeof(IBOColTabControl), selectorPanel.Controls[2]);
            Assert.IsInstanceOf(typeof(IButtonGroupControl), selectorPanel.Controls[1]);
            //Assert.IsInstanceOf(typeof(IPanel), selectorPanel.Controls[3]);
            //Assert.AreEqual(DockStyle.Top, selectorPanel.Controls[3].Dock);
            Assert.AreEqual(DockStyle.Bottom, selectorPanel.Controls[1].Dock);
            //Assert.AreEqual(DockStyle.Fill, selectorPanel.Controls[1].Dock);
            Assert.AreEqual(DockStyle.Fill, selectorPanel.Controls[0].Dock);
        }
//
        //[Test]
        //public void Test_SelectorPanelTopButtonPanel()
        //{
        //    //--------------- Set up test pack ------------------
        //    //--------------- Test Preconditions ----------------
        //    //--------------- Execute Test ----------------------
        //    DMSolutionControl solutionControl = new DMSolutionControl(new ControlFactoryWin());
        //    //--------------- Test Result -----------------------
        //    IPanel selectorPanel = (IPanel)solutionControl.Controls[0];
        //    //IPanel topPanel = (IPanel)selectorPanel.Controls[3];
        //    Assert.AreEqual(1, topPanel.Controls.Count);
        //    Assert.IsInstanceOf(typeof(IButton), topPanel.Controls[0]);
        //    IButton gridButton = (IButton)topPanel.Controls[0];
        //    Assert.AreEqual("Grid", gridButton.Text);
        //}

        [Test]
        public void Test_SelectorPanelBottomButtonPanel()
        {
            //--------------- Set up test pack ------------------
            //--------------- Test Preconditions ----------------
            //--------------- Execute Test ----------------------
            DMSolutionControl solutionControl = new DMSolutionControl(new ControlFactoryWin());
            //--------------- Test Result -----------------------
            IPanel selectorPanel = (IPanel)solutionControl.Controls[0];
            IButtonGroupControl buttonGroupControl = (IButtonGroupControl)selectorPanel.Controls[1];
            Assert.AreEqual(2, buttonGroupControl.Controls.Count);
            Assert.IsNotNull(buttonGroupControl["New"]);
            Assert.IsNotNull(buttonGroupControl["Delete"]);
            //Assert.IsNotNull(buttonGroupControl["Cancel"]);
        }

        //[Ignore("Cannot get this to work")]
        ////TODO: Ignored Test - Cannot get this to work
        //[Test]
        //public void Test_GridButtonClick()
        //{
        //    //--------------- Set up test pack ------------------
        //    //IFormHabanero form = GlobalUIRegistry.ControlFactory.CreateForm();
        //    DMSolutionControl solutionControl = new DMSolutionControl(new ControlFactoryWin());
        //    //form.Controls.Add(solutionControl);
        //    IPanel selectorPanel = (IPanel)solutionControl.Controls[0];
        //    IPanel topPanel = (IPanel)selectorPanel.Controls[3];
        //    IButton gridButton = (IButton)topPanel.Controls[0];
        //    //--------------- Test Preconditions ----------------
        //    Assert.AreEqual("Grid", gridButton.Text);
        //    Assert.IsFalse(solutionControl.DMClassGridSelectorControl.Visible);
        //    Assert.IsTrue(solutionControl.TreeViewSelectorControl.Visible);
        //    //--------------- Execute Test ----------------------
        //    gridButton.PerformClick();
        //    //--------------- Test Result -----------------------
        //    Assert.IsTrue(solutionControl.DMClassGridSelectorControl.Visible);
        //    Assert.IsFalse(solutionControl.TreeViewSelectorControl.Visible);
        //    Assert.AreEqual("Tree", gridButton.Text);
        //}

        [Test]
        public void TestSetSolutionViewModelInfo()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
            TestUtilsShared.CreateSavedDMClass(dmSolution.DefaultAssembly);
            TestUtilsShared.CreateSavedDMClass(dmSolution.DefaultAssembly);
            DMSolutionControl control =
                new DMSolutionControl(new ControlFactoryWin());
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            control.Solution = dmSolution;
            //---------------Test Result -----------------------
            Assert.AreSame(dmSolution, control.Solution);
            Assert.AreSame(dmSolution, control.DMClassGridSelectorControl.Solution);
            //Assert.AreSame(dmSolution, control.TreeViewSelectorControl.DMSolution);
        }

        [Test]
        public void TestDisabledAtCreation()
        {
            //---------------Execute Test ----------------------
            DMSolutionControl control =
                new DMSolutionControl(new ControlFactoryWin());
            //---------------Test Result -----------------------

            Assert.IsFalse(control.Enabled);
        }

        [Test]
        public void TestSetEnables()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
            DMSolutionControl control =
                new DMSolutionControl(new ControlFactoryWin());

            //---------------Execute Test ----------------------
            control.Solution = dmSolution;
            //---------------Test Result -----------------------
            Assert.IsTrue(control.Enabled);
        }

        [Test]
        public void TestSetToNullDisables()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
            DMSolutionControl control =
                new DMSolutionControl(new ControlFactoryWin());
            control.Solution = dmSolution;
            //---------------Execute Test ----------------------
            control.Solution = null;
            //---------------Test Result -----------------------
            Assert.IsFalse(control.Enabled);
        }

        //TODO mark 04 Sep 2009: Need to get rid of these Control.Assembly tests
        //[Test]
        //public void TestSetCreatesSingleTabForSingleAssembly()
        //{
        //    //---------------Set up test pack-------------------
        //    DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
        //    DMSolutionControl control =
        //        new DMSolutionControl(new ControlFactoryWin());
            
        //    //---------------Execute Test ----------------------
        //    control.Solution = dmSolution;
        //    //---------------Test Result -----------------------
        //    Assert.AreEqual(1, control.Assemblies.Count);
        //}

        //[Test]
        //public void TestSetCreatesTabPerAssembly()
        //{
        //    //---------------Set up test pack-------------------
        //    DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
        //    dmSolution.CreateAssembly("Assembly2").Save();
        //    dmSolution.CreateAssembly("Assembly3").Save();

        //    DMSolutionControl control =
        //        new DMSolutionControl(new ControlFactoryWin());
            
        //    //---------------Execute Test ----------------------
        //    control.Solution = dmSolution;
        //    //---------------Test Result -----------------------
        //    Assert.AreEqual(3, control.Assemblies.Count);
        //}
        
        //[Test]
        //public void TestSetBusinessObject()
        //{
        //    //---------------Set up test pack-------------------
        //    DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
        //    DMAssembly assembly = dmSolution.CreateAssembly("assembly2");
        //    DMSolutionControl control =
        //        new DMSolutionControl(new ControlFactoryWin());
        //    control.Solution = dmSolution;
        //    //---------------Assert Precondition----------------

        //    //---------------Execute Test ----------------------
        //    control.Assembly = assembly;
        //    //---------------Test Result -----------------------
        //    Assert.AreSame(assembly, control.Assembly);
        //}

        [Ignore("Changing how this works")] 
        [Test]
        public void TestAssemblySelectedEvent()
        {
//            //---------------Set up test pack-------------------
//            DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
//            DMAssembly assembly = dmSolution.CreateAssembly("assembly2");
//            DMSolutionControl control =
//                new DMSolutionControl(new ControlFactoryWin());
//            bool fired = false;
//            DMAssembly selected = null;
//            control.Solution = dmSolution;
//            //---------------Assert PreConditions---------------     
//            Assert.AreNotSame(selected, control.Assembly);
//            //---------------Execute Test ----------------------
//            control.AssemblySelected += (sender,e) => 
//                    {
//                        fired = true;
//                        selected = e.BusinessObject;
//                    };
//            control.Assembly = assembly;
//            //---------------Test Result -----------------------
//
//            Assert.IsTrue(fired);
//            Assert.AreSame(selected, control.Assembly);
//            //---------------Tear Down -------------------------          
        }
//
        //TODO Brett 26 Mar 2009: Removed because the Grid was giving issues.
//        [Test]
//        public void TestSelectClassGoesToCorrectAssembly()
//        {
//            //---------------Set up test pack-------------------
//            DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
//            DMAssembly assembly = dmSolution.CreateAssembly("assembly2");
//            DMClass class1 = assembly.CreateClass("Class1");
//            DMSolutionControl control =
//               new DMSolutionControl(new ControlFactoryWin());
//            control.Solution = dmSolution;
//
//            //---------------Execute Test ----------------------
//            control.Class = class1;
//            //---------------Test Result -----------------------
//            Assert.AreSame(assembly, control.Assembly);
//            //---------------Tear Down -------------------------          
//        }

//        [Test]
//        public void TestSelectClassFiresClassSelectedEvent()
//        {
//            //---------------Set up test pack-------------------
//            DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
//            DMAssembly assembly = dmSolution.CreateAssembly("assembly2");
//            DMClass class1 = assembly.CreateClass("Class1");
//            DMSolutionControl control =
//               new DMSolutionControl(new ControlFactoryWin());
//            control.Solution = dmSolution;
//            bool fired = false;
//            DMClass selected = null;
//            //---------------Execute Test ----------------------
//            control.BusinessObjectSelected += (sender, e) =>
//            {
//                fired = true;
//                selected = (DMClass) e.BusinessObject;
//            };
//            control.Class = class1;
//            //---------------Test Result -----------------------
//
//            Assert.IsTrue(fired);
//            Assert.AreSame(selected, control.Class);
//            //---------------Tear Down -------------------------          
//        }

        [Test]
        public void Test_GetDefaultBOEditorForm_AssemblyControlMapper_HasCorrectBusinessObjectCollection()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            DMSolution solution = (DMSolution) dmClass.Solution;
            DMAssembly assembly = solution.CreateAssembly(TestUtilsShared.GetRandomString());
            DMSolutionControl control = new DMSolutionControl(new ControlFactoryWin());
            control.Solution = solution;
            //---------------Assert Precondition----------------
            Assert.AreEqual(2, solution.Assemblies.Count);

            //---------------Execute Test ----------------------
            IDefaultBOEditorForm defaultBOEditorForm = control.GetDefaultBOEditorForm(assembly.Classes.CreateBusinessObject());
            //---------------Test Result -----------------------
            IPanelInfo panelInfo = defaultBOEditorForm.PanelInfo;
            RelationshipComboBoxMapper controlMapper =
                (RelationshipComboBoxMapper)panelInfo.FieldInfos["Assembly"].ControlMapper;
            IBusinessObjectCollection businessObjectCollection = controlMapper.BusinessObjectCollection;
            Assert.IsNotNull(businessObjectCollection);
            Assert.AreEqual(2, businessObjectCollection.Count);
            Assert.AreEqual(3, controlMapper.Control.Items.Count);
        }

        [Test]
        public void Test_DeleteButtonClick_ShouldRaiseEvent()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            DMSolution solution = (DMSolution) dmClass.Solution;
            DMSolutionControl control = new DMSolutionControl(new ControlFactoryWin());
            control.Solution = solution;
            bool deleteEventFired = false;
            IPanel selectorPanel = (IPanel)control.Controls[0];
            IButtonGroupControl buttonGroupControl = (IButtonGroupControl)selectorPanel.Controls[1];
            control.DeleteClicked += (sender, e) => deleteEventFired = true;
            //--------------- Test Preconditions ----------------
            Assert.IsTrue(control.Enabled);
            Assert.IsNotNull(buttonGroupControl);
            Assert.IsFalse(deleteEventFired);
           //--------------- Execute Test ----------------------
            buttonGroupControl["Delete"].PerformClick();
           //--------------- Test Result -----------------------
            Assert.IsTrue(deleteEventFired);
        }

        public void Test_CancelButtonClick_ShouldRaiseEvent()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            DMSolution solution = (DMSolution) dmClass.Solution;
            DMSolutionControl control = new DMSolutionControl(new ControlFactoryWin());
            control.Solution = solution;
            bool cancelEventFired = false;
            IPanel selectorPanel = (IPanel)control.Controls[0];
            IButtonGroupControl buttonGroupControl = (IButtonGroupControl)selectorPanel.Controls[2];
            control.CancelClicked += (sender, e) => cancelEventFired = true;
            //--------------- Test Preconditions ----------------
            Assert.IsTrue(control.Enabled);
            Assert.IsNotNull(buttonGroupControl);
            Assert.IsFalse(cancelEventFired);
            //--------------- Execute Test ----------------------
            buttonGroupControl["Cancel"].PerformClick();
            //--------------- Test Result -----------------------
            Assert.IsTrue(cancelEventFired);
        }

        [Test]
        public void Test_CreateNewClass_WhenSolutionNull_ShouldNotAddNewClassToSolution()
        {
            //---------------Set up test pack-------------------
            var dmSolution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            dmSolution.DefaultAssembly = null;
            var control = new DMSolutionControl(new ControlFactoryWin());
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmSolution);
            Assert.IsNull(control.Solution);
            Assert.IsNull(dmSolution.DefaultAssembly);
            Assert.AreEqual(2, dmSolution.AllClasses.Count);
            //---------------Execute Test ----------------------
            control.CreateNewClass();
            //---------------Test Result -----------------------
            Assert.AreEqual(2, dmSolution.AllClasses.Count);
        }

        [Test]
        public void Test_CreateNewClass_WhenDefaultAssemblyNullAndSolutionHasAssemblies_ShouldSetDefaultAssemblyOnSolution()
        {
            //---------------Set up test pack-------------------
            var dmSolution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            dmSolution.DefaultAssembly = null;
            var control = new DMSolutionControlFake(new ControlFactoryWin());
            control.Solution = dmSolution;
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmSolution);
            Assert.IsNotNull(control.Solution);
            Assert.Greater(dmSolution.Assemblies.Count, 0);
            Assert.IsNull(dmSolution.DefaultAssembly);
            Assert.AreEqual(2, dmSolution.AllClasses.Count);
            //---------------Execute Test ----------------------
            control.CreateNewClass();
            //---------------Test Result -----------------------
            Assert.IsNotNull(dmSolution.DefaultAssembly);
        }

        [Test]
        public void Test_CreateNewClass_WhenDefaultAssemblyNullAndSolutionHasNoAssemblies_ShouldNotSetDefaultAssemblyOnSolution()
        {
            //---------------Set up test pack-------------------
            var dmSolution = TestUtilsDMSolution.CreateUnsavedDefaultDMSolution();
            dmSolution.DefaultAssembly = null;
            var control = new DMSolutionControlFake(new ControlFactoryWin());
            control.Solution = dmSolution;
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmSolution);
            Assert.IsNotNull(control.Solution);
            Assert.AreEqual(0, dmSolution.Assemblies.Count);
            Assert.IsNull(dmSolution.DefaultAssembly);
            Assert.AreEqual(0, dmSolution.AllClasses.Count);
            //---------------Execute Test ----------------------
            control.CreateNewClass();
            //---------------Test Result -----------------------
            Assert.IsNull(dmSolution.DefaultAssembly);
        }

        [Test]
        public void Test_CreateNewClass_WhenDefaultAssemblyNullAndSolutionHasAssemblies_ShouldAddNewClassToSolution()
        {
            //---------------Set up test pack-------------------
            var dmSolution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            dmSolution.DefaultAssembly = null;
            var control = new DMSolutionControlFake(new ControlFactoryWin());
            control.Solution = dmSolution;
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmSolution);
            Assert.IsNotNull(control.Solution);
            Assert.Greater(dmSolution.Assemblies.Count, 0);
            Assert.IsNull(dmSolution.DefaultAssembly);
            Assert.AreEqual(2, dmSolution.AllClasses.Count);
            //---------------Execute Test ----------------------
            control.CreateNewClass();
            //---------------Test Result -----------------------
            Assert.IsNotNull(dmSolution.DefaultAssembly);
            Assert.AreEqual(3, dmSolution.AllClasses.Count);
        }

        [Test]
        public void Test_CreateNewClass_WithDefaultAssembly_ShouldAddNewClassToSolution()
        {
            //---------------Set up test pack-------------------
            var dmSolution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            var assembly = dmSolution.DefaultAssembly;
            var control = new DMSolutionControlFake(new ControlFactoryWin());
            control.Solution = dmSolution;
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmSolution);
            Assert.IsNotNull(control.Solution);
            Assert.IsNotNull(assembly);
            Assert.AreEqual(2, assembly.Classes.Count);
            Assert.AreEqual(2, dmSolution.AllClasses.Count);
            //---------------Execute Test ----------------------
            control.CreateNewClass();
            //---------------Test Result -----------------------
            Assert.AreEqual(3, dmSolution.AllClasses.Count);
            Assert.AreEqual(3, assembly.Classes.Count);
            Assert.IsTrue(dmSolution.AllClasses[2].Status.IsDirty, "This class has not been saved because it is saved in the OK Click Handle.");
        }

        //[Test]
        //public void Test_SelectClass_WhenTreeViewVisible_ShouldBeSelectedObjectOnTreeViewSelectorControl()
        //{
        //    //---------------Set up test pack-------------------
        //    DMClass dmClass = TestUtilsShared.CreateSavedDMClass();
        //    DMSolution solution = dmClass.Solution;
        //    DMSolutionControl control = new DMSolutionControl(new ControlFactoryWin());
        //    control.Solution = solution;
        //    DMClassTreeViewSelectorControl treeViewSelectorControl = control.DMClassTreeViewSelectorControl;
        //    TreeViewController treeViewController = treeViewSelectorControl.TreeViewController;
        //    ITreeNode assemblyNode = treeViewController.GetBusinessObjectTreeNode(dmClass.Assembly);
        //    ReflectionUtilities.ExecutePrivateMethod(treeViewController, "ExpandNode", assemblyNode);
        //    ReflectionUtilities.ExecutePrivateMethod(treeViewController, "ExpandNode", assemblyNode.Nodes[0]);
        //    //---------------Assert Precondition----------------
        //    Assert.IsNotNull(dmClass);
        //    Assert.IsTrue(control.DMClassTreeViewSelectorControl.Visible);
        //    Assert.IsFalse(control.DMClassGridSelectorControl.Visible);
        //    //---------------Execute Test ----------------------
        //    control.SelectClass(dmClass);
        //    //---------------Test Result -----------------------
        //    ITreeNode node = treeViewController.GetBusinessObjectTreeNode(dmClass);
        //    Assert.IsNotNull(node);
        //    Assert.AreSame(node, treeViewSelectorControl.TreeView.SelectedNode);
        //    Assert.AreSame(dmClass, control.DMClass);
        //}

        [Test]
        public void Test_SelectClass_WhenGridVisible_ShouldBeSelectedObjectOnDMClassGridSelectorControl()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            DMSolution solution = (DMSolution) dmClass.Solution;
            DMSolutionControl control = new DMSolutionControl(new ControlFactoryWin());
            control.Solution = solution;
            //control.GridButton.PerformClick();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmClass);
            Assert.IsTrue(control.DMClassGridSelectorControl.Visible);
            //Assert.IsFalse(control.DMClassTreeViewSelectorControl.Visible);
            //---------------Execute Test ----------------------
            control.SelectClass(dmClass);
            //---------------Test Result -----------------------
            Assert.AreSame(dmClass, control.DMClassGridSelectorControl.SelectedBusinessObject);
            Assert.AreSame(dmClass, control.DMClass);
        }

    }

    public class DMSolutionControlFake : DMSolutionControl
    {
        public DMSolutionControlFake(IControlFactory controlFactory) : base(controlFactory)
        {
        }

        public override void ShowDMClassForm(IDefaultBOEditorForm defaultBOEditorForm)
        {
            
        }
    }
}
